package com.wtwd.wtwddevice.listener.deviceServerMsg.handler.impl;

import com.wtwd.common.google.service.GoogleService;
import com.wtwd.device.annotation.MsgType;
import com.wtwd.device.constant.*;
import com.wtwd.device.model.Location;
import com.wtwd.device.mqtentity.MessageBase;
import com.wtwd.device.protocol.AppProtocol;
import com.wtwd.device.protocol.WTProtocol;
import com.wtwd.device.util.DateUtils;
import com.wtwd.device.util.StringUtils;
import com.wtwd.wtwddevice.listener.deviceServerMsg.handler.IMsgHandler;
import com.wtwd.wtwddevice.model.entity.LastLocationData;
import com.wtwd.wtwddevice.model.entity.LocationData;
import com.wtwd.wtwddevice.mq.PushMsgService;
import com.wtwd.wtwddevice.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@MsgType(MsgTypeEnum.LOCATION_INFO_GET)
@Component
public class LocationInfoGetHandler implements IMsgHandler {

    @Resource
    private ILastLocationDataService lastLocationDataService;

    @Resource
    private ILocationDataService locationDataService;

    @Resource
    private IDeviceService deviceService;

    @Resource
    private ILocationService locationService;

    @Resource
    private PushMsgService msgService;

    @Resource
    private IAppCommService appCommService;


    @Resource
    private GoogleService googleService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleMsg(MessageBase messageBase) {

        WTProtocol wtProtocol = messageBase.getWtProtocol();
        String body = wtProtocol.getBody();
        String[] split = body.split(SeparatorConstant.CMD_BODY_SEGMENTATION);
        if (split.length < 3) return;
        String gpsLocation = split[0];
        String lbsLocation = split[1];
        String wifiLocation = split[2];
        Long deviceId = deviceService.getDeviceIdByImei(wtProtocol.getImei());
        if (deviceId == null || deviceId == 0) {
            return;
        }
        List<LocationData> locationDatas = dealGpsData(deviceId, gpsLocation);
        if (locationDatas == null || locationDatas.size() == 0) {//说明gps无数据,采用 lbswifi数据
            LocationData data = dealLbsOrWifi(wtProtocol.getImei(), lbsLocation, wifiLocation);
            if (data != null) {
                data.setLocationTime(wtProtocol.getTime());
                locationDatas.add(data);
            }
        }
        if (locationDatas != null && locationDatas.size() > 0) {
            locationDataService.saveBatch(locationDatas);
        }
        LastLocationData lastLocationData = new LastLocationData();
        if (locationDatas.size() == 1) {//
            BeanUtils.copyProperties(locationDatas.get(0), lastLocationData);
        } else {
            LocationData data = locationDatas.stream().max(Comparator.comparing(LocationData::getLocationTime))
                    .get();
            BeanUtils.copyProperties(data, lastLocationData);
        }
        //找出最后一条定位并保存
        lastLocationDataService.insertOrUpdate(lastLocationData);
        wtProtocol.setTime(DateUtils.format(new Date(), DateUtils.dateFormat15));
        wtProtocol.setBody(String.valueOf(AnswerStateEnum.NORMAL.getState()));
        wtProtocol.setBodyLength(wtProtocol.getBody().length());
        wtProtocol.setMesType(CmdTypeEnum.REPORT_RESPONSE.getCmdType().toString());
        msgService.pushToDevice(messageBase.getForm(),
                MessageBase.builder().deviceKey(wtProtocol.getImei())
                        .wtProtocol(wtProtocol)
                        .build());
        //推送定位到app
        if (locationDatas != null && locationDatas.size() > 0) {
            List<Location> locations = new ArrayList<>();
            for (LocationData locationData : locationDatas) {
                Location location = new Location();
                BeanUtils.copyProperties(locationData, location);
                locations.add(location);
            }
            AppProtocol appProtocol = AppProtocol.builder()
                    .imei(wtProtocol.getImei())
                    .cmdName(MsgTypeEnum.APP_LOCATION_INFO_GET.getCmdName())
                    .data(locations)
                    .build();
            appCommService.pushDeviceState(deviceId, appProtocol);
        }
    }


    /**
     * 处理 lbs 定位
     *
     * @param lbsStr
     * @return
     */
    private LocationData dealLbsOrWifi(String imei, String lbsStr, String wifiStr) {
        ArrayList<String> lbs = new ArrayList<>();
        String[] lbsGroup = lbsStr.split(SeparatorConstant.LOCATION_SPLIT);
        String mcc = lbsGroup[0];
        String mnc = lbsGroup[1];
        String lac = lbsGroup[2];
        String cid = lbsGroup[3];
        String lbsData = mcc.concat(SeparatorConstant.COMMA).concat(mnc).concat(SeparatorConstant.COMMA).concat(lac).concat(SeparatorConstant.COMMA)
                .concat(cid);
        lbs.add(lbsData);
        String[] wifiGroup = wifiStr.split(SeparatorConstant.POUND_SIGN);
        ArrayList<String> wifiList = new ArrayList<>();
        for (String wifi : wifiGroup) {
            String[] split = wifi.split(SeparatorConstant.LOCATION_SPLIT);
            String wifiName = split[0];
            String mac = split[1];
            String signalStrength = split[2];
            String wifiData = mac.concat(SeparatorConstant.COMMA)
                    .concat(signalStrength);
            wifiList.add(wifiData);
        }
        LocationData location = locationService.getLocationByLbsOrWifi(imei, lbs, wifiList, null, false);
        if (location!=null){
            if (location.getLocationType().equals(LocationTypeEnum.LPS.getType())){
                location.setLocationType(LocationTypeEnum.INITIATIVE_LPS.getType());
            }else if (location.getLocationType().equals(LocationTypeEnum.WIFI.getType())){
                location.setLocationType(LocationTypeEnum.INITIATIVE_WIFI.getType());
            }
        }
        return location;
    }


    /**
     * 处理Gps
     *
     * @param gpsStr
     * @return
     */
    private List<LocationData> dealGpsData(Long deviceId, String gpsStr) {
        String[] gps = gpsStr.split(SeparatorConstant.LOCATION_SPLIT);
        List<LocationData> locationDatas = new ArrayList<>();
        for (String gp : gps) {
            String locationState = gp.substring(0, 1);
            if (LocationTypeNum.LOCATION_SUCCESS.getType().equals(locationState)) {//GPS定位
                LocationData data = new LocationData();
                String lng = gp.substring(2, 2 + 10);//精度
                String lat = gp.substring(13, 13 + 9);//维度
                if (!notLocation(lat) || !notLocation(lng)) {
                    break;
                }
                String lngMake = gp.substring(1, 2);//精度标识
                String latMake = gp.substring(12, 13);//维度标识
                String time = gp.substring(23, 23 + 14);
                data.setLat(lat);
                data.setLng(lng);
                data.setLocationType(LocationTypeEnum.INITIATIVE_GPS.getType());
                data.setDeviceId(deviceId);
                data.setLocationTime(time);
                locationDatas.add(data);
            }
        }
        return locationDatas;
    }


    private boolean notLocation(String data) {
        if (StringUtils.isEmpty(data) || data.equals("0000.0000")) {
            return false;
        }
        return true;
    }
}
